Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wait until the desktop ends starting up #231

Merged
merged 4 commits into from
Sep 17, 2020

Conversation

rastersoft
Copy link

@rastersoft rastersoft commented Apr 25, 2020

Gnome Shell enables the extensions before the desktop itself is ready to accept widgets. This can result in errors. In the case of appindicator, it results in applications that are launched during startup not showing an indicator because, when the extension tries to add the icon to the Gnome Shell interface, it still isn't ready for that, thus failing. But other applications, launched after the Shell has completed the startup process, will work fine.

This patch fixes this by checking in the enable() method if Gnome Shell is still starting up, in which case it waits until the startup-complete signal is triggered before continuing.

Fix #235

Gnome Shell enables the extensions before the desktop itself is
ready to accept widgets. This can result in errors. In the case
of appindicator, it results in applications that are launched
during startup not showing an indicator because, when the
extension tries to add the icon to the Gnome Shell interface,
it still isn't ready for that, thus failing. But other applications,
launched after the Shell has completed the startup process,
will work fine.

This patch fixes this by checking in the `enable()` method if
Gnome Shell is still starting up, in which case it waits until
the `startup-complete` signal is triggered before continuing.
@rastersoft rastersoft force-pushed the wait_until_shell_ends_startup branch from b2aff4b to b2f70de Compare April 25, 2020 11:55
@terencode
Copy link

This PR has the opposite effect for me:

Without it, I can't reproduce applications not showing their icon but with it, some icons actually disappear.

@terencode
Copy link

Nevermind I think it's working correctly, it might have been a combination of an outdated .desktop not starting and also systemd-networkd-wait-online failing. Do you know how this startup-complete signal is determined?

@terencode
Copy link

Nevermind again it is not, with my last reboots I got 3 appindicators shown out of the 5. The 2 not displayed were correctly launched as they appeared in the list of open applications, just no appindicators.

@rastersoft
Copy link
Author

Yes, it is still happening to me, but before I never had the icon; with this patch I have it sometimes.

About the startup-complete signal, it is emitted by gnome shell in the js/ui/layout.js, when the startup animation is complete. We had to use it in desktop-icons to ensure that the desktop was painted only after the system was fully ready.

@rastersoft
Copy link
Author

Just a question... Those two apps that don't show, are using libappindicator? Maybe the problem is there...

@terencode
Copy link

They are using libappindicator, I can interact with them with the usual menu.

@rastersoft
Copy link
Author

Mmm... The extension returned this error when it failed... I'm going to investigate from here:

may 16 10:33:31 debian gnome-shell[7044]: gtk_icon_theme_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
may 16 10:33:31 debian gnome-shell[7044]: JS ERROR: TypeError: src is null
                                          connectSmart4A@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/util.js:189:21
                                          connectSmart@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/util.js:214:31
                                          _init@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:325:14
                                          _init@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/indicatorStatusIcon.js:42:25
                                          _registerItem@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/statusNotifierWatcher.js:98:22
                                          _ensureItemRegistered@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/statusNotifierWatcher.js:128:14
                                          RegisterStatusNotifierItemAsync@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/statusNotifierWatcher.js:175:14
                                          _handleMethodCall@resource:///org/gnome/gjs/modules/core/overrides/Gio.js:371:35
                                          _wrapJSObject/<@resource:///org/gnome/gjs/modules/core/overrides/Gio.js:404:34
may 16 10:33:31 debian gnome-shell[7044]: gtk_icon_theme_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
may 16 10:33:31 debian gnome-shell[7044]: JS ERROR: Exception in callback for signal: icon: Error: Argument 'filename' (type filename) may not be null
                                          _createIconByName@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:406:26
                                          _cacheOrCreateIconByName@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:368:14
                                          _updateIconByType@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:574:18
                                          _updateIcon@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:601:14
                                          _emit@resource:///org/gnome/gjs/modules/core/_signals.js:133:47
                                          _onPropertiesChanged/<@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:220:22
                                          _onPropertiesChanged@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:214:15
may 16 10:33:31 debian gnome-shell[7044]: registrando /org/ayatana/NotificationItem/Cronopete en :1.62, objeto /org/ayatana/NotificationItem/Cronopete
may 16 10:33:31 debian gnome-shell[7044]: gtk_icon_theme_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
may 16 10:33:31 debian gnome-shell[7044]: JS ERROR: TypeError: src is null
                                          connectSmart4A@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/util.js:189:21
                                          connectSmart@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/util.js:214:31
                                          _init@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:325:14
                                          _init@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/indicatorStatusIcon.js:42:25
                                          _registerItem@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/statusNotifierWatcher.js:98:22
                                          _seekStatusNotifierItems/</<@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/statusNotifierWatcher.js:143:26
                                          introspectBusObject/<@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/util.js:146:21
may 16 10:33:31 debian gnome-shell[7044]: gtk_icon_theme_get_for_screen: assertion 'GDK_IS_SCREEN (screen)' failed
may 16 10:33:31 debian gnome-shell[7044]: JS ERROR: Exception in callback for signal: icon: Error: Argument 'filename' (type filename) may not be null
                                          _createIconByName@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:406:26
                                          _cacheOrCreateIconByName@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:368:14
                                          _updateIconByType@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:574:18
                                          _updateIcon@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:601:14
                                          _emit@resource:///org/gnome/gjs/modules/core/_signals.js:133:47
                                          _onPropertiesChanged/<@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:220:22
                                          _onPropertiesChanged@/home/raster/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:214:15

It seems that the reason for not showing sometimes the appindicators
during startup is because Gtk.IconTheme.get_default() returns NULL.
This seems to happen only very early during startup, so this patch
waits until it returns a valid value before continuing enabling
the extension.

Of course, this patch is just a hack. If this really fixes the
problem, the bug must be fixed upstream.
@rastersoft
Copy link
Author

I added a second patch to this MR that, during startup, waits until Gtk.IconTheme.get_default() returns a valid value instead of NULL. I rebooted several times and it seems to work. Of course, this is just an ugly hack, but if it really works, then we have something to report in the mutter/gnome-shell repository...

@terencode
Copy link

Tried it but does not fix anything for me. Some apps start (the window), but aren't able to get their appindicator in the panel.

@rastersoft
Copy link
Author

Can you spot any error with journalctl /usr/bin/gnome-shell?

@terencode
Copy link

Only thing I see is

mai 16 19:51:58 terence-desktop gnome-shell[2045]: JS ERROR: Exception in callback for signal: icon: Error: Argument 'filename' (type filename) may not be null
                                                   _createIconByName@/home/terence/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:421:26
                                                   _cacheOrCreateIconByName@/home/terence/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:383:14
                                                   _updateIconByType@/home/terence/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:589:18
                                                   _updateIcon@/home/terence/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:622:14
                                                   _emit@resource:///org/gnome/gjs/modules/core/_signals.js:133:47
                                                   _onPropertiesChanged/<@/home/terence/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:221:22
                                                   _onPropertiesChanged@/home/terence/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/appIndicator.js:215:15
                                                   refreshPropertyOnProxy/<@/home/terence/.local/share/gnome-shell/extensions/appindicatorsupport@rgcjonas.gmail.com/util.js:51:19
mai 16 19:51:58 terence-desktop appindicatorsupport@rgcjonas.gmail.com[2045]: discord1, Impossible to lookup icon for 'discord1_1-panel'

but that might be unrelated.

@rastersoft
Copy link
Author

Mmm... not sure... I was receiving exactly that same error, with also the one of get_for_screen()...

@rastersoft
Copy link
Author

Added another check to manage that case. Can you test it again?

@rastersoft
Copy link
Author

Did a little extra change. Test it now again, please.

@terencode
Copy link

Tested it including 6b5bd5c and it seems to behave correctly now :)

@rastersoft
Copy link
Author

Perfect. So there were two problems:

  • sometimes, during early startup, it's not possible to get a pointer to IconTheme
  • sometimes, during early startup, it's not possible to get icon names

@rastersoft rastersoft force-pushed the wait_until_shell_ends_startup branch from 6b5bd5c to 0b1b45f Compare May 16, 2020 22:30
@rastersoft
Copy link
Author

Squashed the last three commits in a single one.

@rastersoft
Copy link
Author

Just one question: is it important the "theme" parameter? I mean: there seems to be some GLib calls for icons, which won't depend on a Gdk.Screen, but doesn't seem to accept a theme.

Gdk.DisplayManager has a signal to specify when the default display
is available. This patch makes use of it to detect when the enable
work can continue.

It also does the waiting for the display and for 'startup-complete'
in parallel.
@rastersoft
Copy link
Author

Ok, now I think we have the right MR: it uses a signal to detect when a display is available, and waits for startup complete in parallel with waiting for the display.

What do you think?

@terencode
Copy link

Yes, it's working correctly :)
It seems before this commit I had some icons still not loaded but from my one reboot with e0dd0df, all are in.

@rastersoft
Copy link
Author

Good!

@terencode
Copy link

Hmm new reboot and one out of the 6 appindicators didn't register: antimicroX
I didn't find anything in the log.

@rastersoft
Copy link
Author

Agh!!

@rastersoft
Copy link
Author

With the previous patch did it register?

Copy link
Collaborator

@3v1n0 3v1n0 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok, just few comments

}

// Ensure that the default Gdk Screen is available
if (Gtk.IconTheme.get_default() == null) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe here would be better to check !Gdk.DisplayManager.get().get_default_display() instead?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gtk.IconTheme.get_default() fails because internally it can't get the default display. In some comments in #mutter they commented that Gtk.IconTheme should not rely on a display (or an screen... now I doubt), because it is an X11 specific structure. So, if in the future, they remove that, Gtk.IconTheme.get_default() will work directly and the extension won't have to wait.

@@ -403,6 +403,13 @@ class AppIndicators_IconActor extends St.Icon {
}

_createIconByName(path, callback) {
if (!path) {
GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure the idle is needed here, can't we just call the callback and return here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I saw it was failing as per 6b5bd5c

Not sure there's another way to avoid.

In any case, pelase save the idle id in the class and disconnect it on destruction.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I call it from IDLE to ensure that the calling code ends anything that is doing before the callback is called. Currently it doesn't matter, but being strict, the code that calls _createIconByName() can legally presume that the callback won't be called until the whole function ended. Calling the callback directly instead of using idle_add can result in breaking that assumption.

About the id: the callback already returns false to remove it, so it doesn't need to be disconnected on destruction. In fact, it MUST be removed after the first execution, or the callback would be called every time there is idle time.

(unless I understood the memory management wrong in these cases)

@terencode
Copy link

With the previous patch did it register?

I think not this one specifically but a few hours ago I rebooted and the discord icon looked like this (the 3 dots):
image

I see this in the log this:

mai 18 21:02:02 terence-desktop appindicatorsupport@rgcjonas.gmail.com[2248]: discord1, Impossible to lookup icon for 'discord1_2-panel'
mai 18 21:02:02 terence-desktop appindicatorsupport@rgcjonas.gmail.com[2248]: unable to update icon for discord1

but I think it was also happening before.

@rastersoft
Copy link
Author

That happens when the panel can't find the icon. That happened to me when, accidentally, I put an incorrect icon name in an indicator. So it can be a bug in the application (setting an incorrect icon name) or a bug in the extension (doesn't search for icons in all possible places).

@Valeryan24
Copy link

Hi, can we hope a quick update of KStatusNotifierItem before Gnome Shell 3.38 / Ubuntu 20.10 ? It's boring to have restarting computer 2 times each time to activate the missing icons... Thanks :)

@terencode
Copy link

terencode commented Oct 12, 2020

After this being merged, I now have again the opposite effect with 2 apps running on startup not having their tray icon shown.
I'd like to revert this to figure out the problem but it now conflicts with the recent changes on top.

@P4Cu
Copy link

P4Cu commented Jan 14, 2021

I did a few experiments and I found the problematic part.

  1. KeepassXC on autostart.
  2. Code:

if (Main.layoutManager._startingUp) {

is triggered as it's not yet ready.
3) StatusNotifierWatcher constructor is not called so we don't have dbus interface yet.
4) KeePassXC is already started and it won't request again (app assumes that indicator will be there)

For me just turning the if to always be false is enough but I understand that in some cases it can have bad consequences so it's not a solution.
Iit looks like dbus interface should be always up but cache things until we're ready to run it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Indicators from apps launched during startup doesn't appear
5 participants